#pragma once

#include <memory>
#include "Connection.hpp"
#include "Reactor.hpp"
#include "HandlerConnection.hpp"
#include "Socket.hpp"

using namespace socket_ns;

class Listener
{
public:
    Listener(int port, HandlerConnection &hc)
        : _port(port),
          _listensock(std::make_unique<TcpSocket>()),
          _hc(hc)
    {
        InetAddr localaddr("0", port);
        _listensock->BuildListenSocket(localaddr);
    }

    void Accepter(Connection *conn)
    {
        InetAddr clientaddr;
        int sockfd = _listensock->Accepter(&clientaddr);
        if (sockfd > 0)
        {
            conn->_R->AddConnetion(
                sockfd,
                EPOLLIN | EPOLLET,
                std::bind(&HandlerConnection::HandlerRecv, &_hc, std::placeholders::_1),
                std::bind(&HandlerConnection::HandlerSend, &_hc, std::placeholders::_1),
                std::bind(&HandlerConnection::HandlerExcept, &_hc, std::placeholders::_1));
        }
    }

    int Sockfd()
    {
        return _listensock->SockFd();
    }
    ~Listener()
    {
        _listensock->Close();
    }

private:
    int _port;
    std::unique_ptr<Socket> _listensock;
    HandlerConnection &_hc;
};